﻿using System.Windows;
using System.Windows.Controls;

namespace MvvmFx.Common.DataTemplateSelector
{
    public class DataContentControl : ContentControl
    {
        #region [ Constructor ]

        /// <summary>
        /// Initializes a new instance of the <see cref="DataContentControl"/> class.
        /// </summary>
        public DataContentControl()
        {
        }

        #endregion

        #region [ ContentTemplateSelectorBase - Dependency Property ]

        /// <summary>
        /// Gets or sets the value of the <see cref="ContentTemplateSelectorBase"/> property.
        /// </summary>
        public DataTemplateSelectorBase ContentTemplateSelectorBase
        {
            get { return (DataTemplateSelectorBase) GetValue(ContentTemplateSelectorProperty); }
            set { SetValue(ContentTemplateSelectorProperty, value); }
        }

        /// <summary>
        /// The <see cref="ContentTemplateSelectorProperty" /> dependency property registered with the 
        /// Microsoft Presentation Foundation (WPF) property system.
        /// </summary>
        public static readonly DependencyProperty ContentTemplateSelectorProperty =
            DependencyProperty.Register("ContentTemplateSelectorBase", typeof(DataTemplateSelectorBase), typeof(DataContentControl), new PropertyMetadata(null, OnContentTemplateSelectorPropertyChanged));

        private static void OnContentTemplateSelectorPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
        {
            DataContentControl contentControl = (DataContentControl) dependencyObject;
            if (contentControl != null)
            {
                contentControl.OnContentTemplateSelectorChanged((DataTemplateSelectorBase) args.OldValue,
                                                                (DataTemplateSelectorBase) args.NewValue);
            }
        }
        
        /// <summary>
        /// On the content template changed, refresh the current conent presenter.
        /// </summary>
        /// <param name="oldValue">The old value for the dependency property.</param>
        /// <param name="newValue">The new value for the depenedency property.</param>
        protected virtual void OnContentTemplateSelectorChanged(DataTemplateSelectorBase oldValue, DataTemplateSelectorBase newValue)
        {
            RefreshContentTemplate();
        }


        #endregion


        #region [ Override Methods ]

        /// <summary>
        /// On the template applied, refresh the content presenter.
        /// </summary>
        public override void OnApplyTemplate()
        {
            RefreshContentTemplate();
        }

        /// <summary> 
        /// Select the appropriate DataTemplate when the Content changes. 
        /// </summary> 
        /// <param name="oldContent">The old Content value.</param> 
        /// <param name="newContent">The new Content value.</param> 
        protected override void OnContentChanged(object oldContent, object newContent)
        {
            base.OnContentChanged(oldContent, newContent);

            RefreshContentTemplate();
        }

        #endregion


        #region [ Private Methods ]

        /// <summary>
        /// Refresh the current content presenter with the associated data template selected.
        /// </summary>
        private void RefreshContentTemplate()
        {
            //Select the appropriate data template.
            DataTemplate template = null;
            if (ContentTemplateSelectorBase != null)
            {
                template = ContentTemplateSelectorBase.SelectTemplate(Content, this);
            }
            ContentTemplate = template;
        }

        #endregion
    }
}